package cn.ztydata.teachingsystem.heaven.service;

import cn.ztydata.teachingsystem.common.Page;
import cn.ztydata.teachingsystem.heaven.cons.Constants;
import cn.ztydata.teachingsystem.heaven.dao.CourseArrangeDao;
import cn.ztydata.teachingsystem.heaven.dao.CourseCodeDao;
import cn.ztydata.teachingsystem.heaven.entity.CourseArrange;
import cn.ztydata.teachingsystem.heaven.exception.ExcelException;
import cn.ztydata.teachingsystem.util.ExcelUtil;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 课程安排业务类
 * Created by wyh on 2015/3/30.
 */
@Service
public class CourseArrangeService extends BaseService {
    @Autowired
    private CourseArrangeDao courseArrangeDao;
    @Autowired
    private CourseCodeDao courseCodeDao;

    /**
     * 读取Excel文件 课程安排
     * @param in 文件输入流
     *
     * @author wyh
     * @since 2015/3/30
     */
    public List<CourseArrange> readFromExcel(InputStream in) throws IOException {
        //定义标题-属性的映射
        LinkedHashMap<String, String> fieldMap = Maps.newLinkedHashMap();
        fieldMap.put("课程代码", "code");
        fieldMap.put("系部编码", "departNum");
        fieldMap.put("起始学年", "startYear");
        fieldMap.put("结束学年", "endYear");
        fieldMap.put("学期", "term");
        fieldMap.put("课程类别", "courseType");

        log.debug("转换Excel课程安排信息为List");
        return ExcelUtil.excelToList(in, CourseArrange.class, fieldMap);
    }

    /**
     * 检查导入课程安排数据中的课程代码冲突
     * @param courseArrangeList 课程安排集合
     *
     * @author wyh
     * @since 2015-03-30
     */
    public void checkForCode(final List<CourseArrange> courseArrangeList) {
        //判断条数
        if (courseArrangeList.size() > Constants.TOTAL_2K) {
            log.debug("导入数据量超过" + Constants.TOTAL_2K);
            throw new ExcelException("导入数据量超过" + Constants.TOTAL_2K);
        }

        //抽取课程代码集合
        Set<String> courseArrangeCodeSet = Sets.newHashSet();
        int index = 1;
        log.debug("循环导入的课程安排集合");
        for (CourseArrange courseArrange : courseArrangeList) {
            if (courseArrange.getCode() == null) {
                log.debug("课程代码 is null");

                throw new ExcelException("导入数据中第" + index + "条数据课程代码为空");
            }

            //检查导入数据中是否存在重复课程代码
            if (courseArrangeCodeSet.contains(courseArrange.getCode())) {
                log.debug("导入数据中的课程代码重复");

                throw new ExcelException("导入数据中第" + index + "条数据的课程代码重复" );
            }

            courseArrangeCodeSet.add(courseArrange.getCode());
            index++;
        }

        //检查导入数据课程代码是否与数据库中记录冲突
        String duplicateNum = courseArrangeDao.getDuplicateCode(courseArrangeCodeSet);
        courseArrangeCodeSet.clear();
        if (duplicateNum != null) {
            log.debug("数据库中存在导入的课程代码");

            throw new ExcelException("课程代码为:" + duplicateNum + "的课程安排已经存在");
        }
    }

    /**
     * 批量新增课程安排
     * @param courseArrangeList 课程安排集合
     *
     * @author wyh
     * @since 2015-03-26
     */
    @Transactional
    public void saveCourseArranges(final List<CourseArrange> courseArrangeList) {
        try {
            //执行批量插入
            courseArrangeDao.saveCourseArranges(courseArrangeList);
        } catch (DataAccessException ex) {
            log.debug("导入课程安排-批量新增异常");

            log.warn("导入课程安排-批量新增异常", ex);
            throw new ExcelException();
        }
    }

    /**
     * 根据系部编码查询课程
     * @param dept 系部代码
     * @return List
     *
     * @author wyh
     * @since 2015-03-30
     */
    public List<Map<String, Object>> getCourseList(String dept){
        log.debug("返回 课程信息");
        return courseArrangeDao.getCourseList(dept);
    }

    /**
     * 课程安排列表
     * @param depart 系部代码
     * @param courseId 课程ID
     * @param startYear 起始学年
     * @param term 学期 0上1下2全部
     * @param page 页码
     * @param pageSize  页数
     * @return page
     *
     * @author wyh
     * @since 2015-03-31
     */
    public Page<CourseArrange> listArrange(String depart, long courseId, String startYear, int term, int page, int pageSize){
        log.debug("返回 课程安排列表");
        //如果课程id为0，传null表示不查询课程id； 如果不为0，查询课程下所有课程代码
        return courseArrangeDao.listArrange(depart, courseId == 0 ? null : courseCodeDao.getCodesById(courseId), startYear, term, page, pageSize);
    }

    /**
     * 学年下拉框
     * @return List
     *
     * @author wyh
     * @since 2015-4-16
     */
    public List<String> getYearList(){
        log.debug("返回 所有学年");
        return courseArrangeDao.getYearList();
    }
}
